package proyecto.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import javax.sql.DataSource;
import proyecto.excepcion.DAOExcepcion;
import proyecto.excepcion.LoginExcepcion;
import proyecto.modelo.Empleado;
import proyecto.modelo.Area;
import proyecto.modelo.Cargo;

public class EmpleadoDAOImpl extends BaseDAO implements EmpleadoDAO {

    private DataSource dataSource;

    public DataSource getDataSource() {
        return dataSource;
    }

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    public Collection<Empleado> buscarPorNombre(String descripcion)
            throws DAOExcepcion {
        String query = "select EMP_CODIGO, are.ARE_CODIGO, are.ARE_DESCRIPCION, car.CAR_CODIGO, car.CAR_DESCRIPCION, EMP_NOMBRE, EMP_APELLIDOPATERNO," +
                " EMP_APELLIDOMATERNO, EMP_FECHANACIMIENTO, EMP_FECHAINGRESO, EMP_SEXO, EMP_SUELDO, " +
                " EMP_JEFE, EMP_CONTRASENA" +
                " FROM Empleado emp, Cargo car, AREA are" +
                " WHERE emp.CAR_CODIGO = car.CAR_CODIGO" +
                " AND emp.ARE_CODIGO = are.ARE_CODIGO" +
                " AND EMP_APELLIDOPATERNO like ?";


        Collection<Empleado> lista = new ArrayList<Empleado>();
        Connection con = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try {
            con = dataSource.getConnection();
            stmt = con.prepareStatement(query);
            stmt.setString(1, "%" + descripcion + "%");

            rs = stmt.executeQuery();
            while (rs.next()) {
                Empleado vo = new Empleado();
                vo.setEmp_Codigo(rs.getString("EMP_CODIGO"));
                vo.setEmp_Nombre(rs.getString("EMP_NOMBRE"));
                vo.setEmp_ApellidoPaterno(rs.getString("EMP_APELLIDOPATERNO"));
                vo.setEmp_ApellidoMaterno(rs.getString("EMP_APELLIDOMATERNO"));
                vo.setEmp_Sexo(rs.getString("EMP_SEXO"));
                vo.setEmp_Sueldo(rs.getDouble("EMP_SUELDO"));
                vo.setEmp_Jefe(rs.getString("EMP_JEFE"));
                vo.setEmp_Contrasena(rs.getString("EMP_CONTRASENA"));
                //vo.setEmp_FechaIngreso(rs.getDate("EMP_FECHAINGRESO"));
                //vo.setEmp_FechaIngreso(rs.getDate("EMP_FECHANACIMIENTO"));

                Area area = new Area();
                area.setAre_Codigo(rs.getInt("ARE_CODIGO"));
                area.setAre_Descripcion(rs.getString("ARE_DESCRIPCION"));

                Cargo cargo = new Cargo();
                cargo.setCar_Codigo(rs.getInt("CAR_CODIGO"));
                cargo.setCar_Descripcion(rs.getString("CAR_DESCRIPCION"));

                vo.setArea(area);
                vo.setCargo(cargo);

                lista.add(vo);
            }
        } catch (SQLException e) {
            System.err.println(e.getMessage());
            throw new DAOExcepcion(e.getMessage());
        } finally {
            this.cerrarResultSet(rs);
            this.cerrarStatement(stmt);
            this.cerrarConexion(con);
        }
        System.out.println(lista.size());
        return lista;
    }

    public Empleado insertar(Empleado vo) throws DAOExcepcion {
        String query = "INSERT INTO empleado" +
                " (" +
                " EMP_CODIGO, ARE_CODIGO, CAR_CODIGO, EMP_NOMBRE, EMP_APELLIDOPATERNO, " +
                " EMP_APELLIDOMATERNO, EMP_SEXO, " +
                " EMP_SUELDO, EMP_JEFE, EMP_CONTRASENA" +
                " )" +
                " VALUES" +
                " (" +
                " ?, ?, ?, ?, ?, ?, ?, ?, ?, ?" +
                " );";
        Connection con = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try {
            con = dataSource.getConnection();
            stmt = con.prepareStatement(query);
            stmt.setString(1, vo.getEmp_Codigo());
            stmt.setInt(2, vo.getArea().getAre_Codigo());
            stmt.setInt(3, vo.getCargo().getCar_Codigo());
            stmt.setString(4, vo.getEmp_Nombre());
            stmt.setString(5, vo.getEmp_ApellidoPaterno());
            stmt.setString(6, vo.getEmp_ApellidoMaterno());
            //stmt.setDate(7, vo.getEmp_FechaNacimiento());
            //stmt.setDate(8, vo.getEmp_FechaIngreso());
            stmt.setString(7, vo.getEmp_Sexo());
            stmt.setDouble(8, vo.getEmp_Sueldo());
            stmt.setString(9, vo.getEmp_Jefe());
            stmt.setString(10, vo.getEmp_Contrasena());

            int i = stmt.executeUpdate();
            if (i != 1) {
                throw new SQLException("No se pudo insertar");
            }
            // Obtener el ultimo id
            int id = 0;
            query = "SELECT LAST_INSERT_ID()";
            stmt = con.prepareStatement(query);
            rs = stmt.executeQuery();
            if (rs.next()) {
                id = rs.getInt(1);
            }

        } catch (SQLException e) {
            System.err.println(e.getMessage());
            throw new DAOExcepcion(e.getMessage());
        } finally {
            this.cerrarResultSet(rs);
            this.cerrarStatement(stmt);
            this.cerrarConexion(con);
        }
        return vo;
    }

    public Empleado obtener(String codigo) throws DAOExcepcion {
        Empleado vo = new Empleado();
        Connection con = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try {
            String query = "select EMP_CODIGO, are.ARE_CODIGO, are.ARE_DESCRIPCION, car.CAR_CODIGO, car.CAR_DESCRIPCION, EMP_NOMBRE, EMP_APELLIDOPATERNO," +
                    " EMP_APELLIDOMATERNO, EMP_FECHANACIMIENTO, EMP_FECHAINGRESO, EMP_SEXO, EMP_SUELDO, " +
                    " EMP_JEFE, EMP_CONTRASENA" +
                    " FROM Empleado emp, Cargo car, AREA are" +
                    " WHERE emp.CAR_CODIGO = car.CAR_CODIGO" +
                    " AND emp.ARE_CODIGO = are.ARE_CODIGO" +
                    " AND EMP_CODIGO = ?";
            con = dataSource.getConnection();
            stmt = con.prepareStatement(query);
            stmt.setString(1, codigo);
            rs = stmt.executeQuery();
            if (rs.next()) {
                vo.setEmp_Codigo(rs.getString("EMP_CODIGO"));
                vo.setEmp_Nombre(rs.getString("EMP_NOMBRE"));
                vo.setEmp_ApellidoPaterno(rs.getString("EMP_APELLIDOPATERNO"));
                vo.setEmp_ApellidoMaterno(rs.getString("EMP_APELLIDOMATERNO"));
                vo.setEmp_Sexo(rs.getString("EMP_SEXO"));
                vo.setEmp_Sueldo(rs.getDouble("EMP_SUELDO"));
                vo.setEmp_Jefe(rs.getString("EMP_JEFE"));
                vo.setEmp_Contrasena(rs.getString("EMP_CONTRASENA"));
                //vo.setEmp_FechaIngreso(rs.getDate("EMP_FECHAINGRESO"));
                //vo.setEmp_FechaIngreso(rs.getDate("EMP_FECHANACIMIENTO"));

                Area area = new Area();
                area.setAre_Codigo(rs.getInt("ARE_CODIGO"));
                area.setAre_Descripcion(rs.getString("ARE_DESCRIPCION"));

                Cargo cargo = new Cargo();
                cargo.setCar_Codigo(rs.getInt("CAR_CODIGO"));
                cargo.setCar_Descripcion(rs.getString("CAR_DESCRIPCION"));

                vo.setArea(area);
                vo.setCargo(cargo);
            }
        } catch (SQLException e) {
            System.err.println(e.getMessage());
            throw new DAOExcepcion(e.getMessage());
        } finally {
            this.cerrarResultSet(rs);
            this.cerrarStatement(stmt);
            this.cerrarConexion(con);
        }
        return vo;
    }

    public void eliminar(String codigo) throws DAOExcepcion {
        String query = "DELETE FROM Empleado WHERE EMP_CODIGO=?";
        Connection con = null;
        PreparedStatement stmt = null;
        try {
            con = dataSource.getConnection();
            stmt = con.prepareStatement(query);
            stmt.setString(1, codigo);
            int i = stmt.executeUpdate();
            if (i != 1) {
                throw new SQLException("No se pudo eliminar");
            }
        } catch (SQLException e) {
            System.err.println(e.getMessage());
            throw new DAOExcepcion(e.getMessage());
        } finally {
            this.cerrarStatement(stmt);
            this.cerrarConexion(con);
        }
    }

    public Empleado actualizar(Empleado vo) throws DAOExcepcion {
        String query = "UPDATE empleado " +
	" SET" +
	" ARE_CODIGO = ? , " +
	" CAR_CODIGO = ? , " +
	" EMP_NOMBRE = ? , " +
	" EMP_APELLIDOPATERNO = ? , " +
	" EMP_APELLIDOMATERNO = ? , " +
	" EMP_FECHANACIMIENTO = ? , " +
	" EMP_FECHAINGRESO = ? , " +
	" EMP_SEXO = ? , " +
	" EMP_SUELDO = ? , " +
	" EMP_JEFE = ? , " +
	" EMP_CONTRASENA = ?" +
	" WHERE" +
	" EMP_CODIGO = ? ;";
        Connection con = null;
        PreparedStatement stmt = null;
        try {
            con = dataSource.getConnection();
            stmt = con.prepareStatement(query);

            stmt.setInt(1, vo.getArea().getAre_Codigo());
            stmt.setInt(2, vo.getCargo().getCar_Codigo());
            stmt.setString(3, vo.getEmp_Nombre());
            stmt.setString(4, vo.getEmp_ApellidoPaterno());
            stmt.setString(5, vo.getEmp_ApellidoMaterno());
            stmt.setDate(6, vo.getEmp_FechaNacimiento());
            stmt.setDate(7, vo.getEmp_FechaIngreso());
            stmt.setString(8, vo.getEmp_Sexo());
            stmt.setDouble(9, vo.getEmp_Sueldo());
            stmt.setString(10, vo.getEmp_Jefe());
            stmt.setString(11, vo.getEmp_Contrasena());
            stmt.setString(12, vo.getEmp_Codigo());

            int i = stmt.executeUpdate();
            if (i != 1) {
                throw new SQLException("No se pudo actualizar");
            }
        } catch (SQLException e) {
            System.err.println(e.getMessage());
            throw new DAOExcepcion(e.getMessage());
        } finally {
            this.cerrarStatement(stmt);
            this.cerrarConexion(con);
        }
        return vo;
    }

    public Collection<Empleado> listar() throws DAOExcepcion {
        Collection<Empleado> lista = new ArrayList<Empleado>();
        Connection con = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try {
            con = dataSource.getConnection();
            String query = "select EMP_CODIGO, are.ARE_CODIGO, are.ARE_DESCRIPCION, car.CAR_CODIGO, car.CAR_DESCRIPCION, EMP_NOMBRE, EMP_APELLIDOPATERNO," +
                " EMP_APELLIDOMATERNO, EMP_FECHANACIMIENTO, EMP_FECHAINGRESO, EMP_SEXO, EMP_SUELDO, " +
                " EMP_JEFE, EMP_CONTRASENA" +
                " FROM Empleado emp, Cargo car, AREA are" +
                " WHERE emp.CAR_CODIGO = car.CAR_CODIGO" +
                " AND emp.ARE_CODIGO = are.ARE_CODIGO";
            stmt = con.prepareStatement(query);
            rs = stmt.executeQuery();
            while (rs.next()) {
                Empleado vo = new Empleado();
               vo.setEmp_Codigo(rs.getString("EMP_CODIGO"));
                vo.setEmp_Nombre(rs.getString("EMP_NOMBRE"));
                vo.setEmp_ApellidoPaterno(rs.getString("EMP_APELLIDOPATERNO"));
                vo.setEmp_ApellidoMaterno(rs.getString("EMP_APELLIDOMATERNO"));
                vo.setEmp_Sexo(rs.getString("EMP_SEXO"));
                vo.setEmp_Sueldo(rs.getDouble("EMP_SUELDO"));
                vo.setEmp_Jefe(rs.getString("EMP_JEFE"));
                vo.setEmp_Contrasena(rs.getString("EMP_CONTRASENA"));
                //vo.setEmp_FechaIngreso(rs.getDate("EMP_FECHAINGRESO"));
                //vo.setEmp_FechaIngreso(rs.getDate("EMP_FECHANACIMIENTO"));

                 Area area = new Area();
                area.setAre_Codigo(rs.getInt("ARE_CODIGO"));
                area.setAre_Descripcion(rs.getString("ARE_DESCRIPCION"));

                Cargo cargo = new Cargo();
                cargo.setCar_Codigo(rs.getInt("CAR_CODIGO"));
                cargo.setCar_Descripcion(rs.getString("CAR_DESCRIPCION"));

                vo.setArea(area);
                vo.setCargo(cargo);
                
                lista.add(vo);
            }

        } catch (SQLException e) {
            System.err.println(e.getMessage());
            throw new DAOExcepcion(e.getMessage());
        } finally {
            this.cerrarResultSet(rs);
            this.cerrarStatement(stmt);
            this.cerrarConexion(con);
        }
        return lista;
    }

    public Empleado validar(String usuario, String clave) throws DAOExcepcion, LoginExcepcion {
        System.out.println("UsuarioDAOImpl: validar: usuario: " + usuario + ", clave: " + clave);
        String query = "select EMP_CODIGO, are.ARE_CODIGO, are.ARE_DESCRIPCION, car.CAR_CODIGO, car.CAR_DESCRIPCION, EMP_NOMBRE, EMP_APELLIDOPATERNO," +
                " EMP_APELLIDOMATERNO, EMP_FECHANACIMIENTO, EMP_FECHAINGRESO, EMP_SEXO, EMP_SUELDO, " +
                " EMP_JEFE, EMP_CONTRASENA" +
                " FROM Empleado emp, Cargo car, AREA are" +
                " WHERE emp.CAR_CODIGO = car.CAR_CODIGO" +
                " AND emp.ARE_CODIGO = are.ARE_CODIGO And EMP_CODIGO=? and EMP_CONTRASENA=?";
        Connection con = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        Empleado vo = new Empleado();
        try {
            con = dataSource.getConnection();
            stmt = con.prepareStatement(query);
            stmt.setString(1, usuario);
            stmt.setString(2, clave);
            rs = stmt.executeQuery();

            if (rs.next()) {
                vo.setEmp_Codigo(rs.getString("EMP_CODIGO"));
                vo.setEmp_Nombre(rs.getString("EMP_NOMBRE"));
                vo.setEmp_ApellidoPaterno(rs.getString("EMP_APELLIDOPATERNO"));
                vo.setEmp_ApellidoMaterno(rs.getString("EMP_APELLIDOMATERNO"));
                vo.setEmp_Sexo(rs.getString("EMP_SEXO"));
                vo.setEmp_Sueldo(rs.getDouble("EMP_SUELDO"));
                vo.setEmp_Jefe(rs.getString("EMP_JEFE"));
                vo.setEmp_Contrasena(rs.getString("EMP_CONTRASENA"));
                //vo.setEmp_FechaIngreso(rs.getDate("EMP_FECHAINGRESO"));
                //vo.setEmp_FechaIngreso(rs.getDate("EMP_FECHANACIMIENTO"));

                Area area = new Area();
                area.setAre_Codigo(rs.getInt("ARE_CODIGO"));
                area.setAre_Descripcion(rs.getString("ARE_DESCRIPCION"));

                Cargo cargo = new Cargo();
                cargo.setCar_Codigo(rs.getInt("CAR_CODIGO"));
                cargo.setCar_Descripcion(rs.getString("CAR_DESCRIPCION"));

                vo.setArea(area);
                vo.setCargo(cargo);
            } else {
                throw new LoginExcepcion("No existe");
            }
        } catch (LoginExcepcion e) {
            System.err.println(e.getMessage());
            throw e;
        } catch (SQLException e) {
            System.err.println(e.getMessage());
            throw new DAOExcepcion(e.getMessage());
        } finally {
            this.cerrarResultSet(rs);
            this.cerrarStatement(stmt);
            this.cerrarConexion(con);
        }
        return vo;
    }
}
